package com.example.usbdemo;

import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.Nullable;

import com.hoho.android.usbserial.driver.UsbSerialDriver;
import com.hoho.android.usbserial.driver.UsbSerialPort;
import com.hoho.android.usbserial.driver.UsbSerialProber;
import com.hoho.android.usbserial.util.SerialInputOutputManager;

import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ConnectService extends Service {

    private final static String TAG = "USB 插拔信息";
    private final static String USB_SERIALPORT_ATTCHED = "HR_USB_SERIALPORT_ATTCHED";
    private final static String USB_SERIALPORT_DETACHED = "HR_USB_SERIALPORT_DETACHED";
    private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";

    private UsbSerialPort mUsbPort;
    private UsbSerialDriver mUsbDriver;
    private UsbDeviceConnection musbDeviceConnection;
    private SerialInputOutputManager mSerialIoManager;
    public final ExecutorService mExecutor = Executors.newSingleThreadExecutor();

    @Override
    public void onCreate() {
        super.onCreate();
        IntentFilter filter = new IntentFilter();
        filter.addAction(USB_SERIALPORT_ATTCHED);
        filter.addAction(USB_SERIALPORT_DETACHED);
        registerReceiver(Br_UsbActionProc, filter);

        IntentFilter permissionintent = new IntentFilter();
        permissionintent.addAction(ACTION_USB_PERMISSION);
        registerReceiver(Br_UsbPermissionProc, permissionintent);

        CheckUsbDevice();

    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private final BroadcastReceiver Br_UsbPermissionProc = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action == null) {
                return;
            }
            switch (action) {
                case ACTION_USB_PERMISSION: {
                    UsbManager usbManager = (UsbManager) getBaseContext().getSystemService(Context.USB_SERVICE);
                    PendingIntent mPendingIntent = PendingIntent.getBroadcast(getBaseContext(), 0, new Intent(ACTION_USB_PERMISSION), 0);
                    for (final UsbDevice usbDevice : usbManager.getDeviceList().values()) {
                        if (usbManager.hasPermission(usbDevice)) {
                            InitSerialPort(usbManager, usbDevice);
                        }
                    }
                }
            }
        }
    };

    /**
     * 初始化串口操作
     * @param usbManager
     * @param usbDevice
     */
    private void InitSerialPort(UsbManager usbManager, UsbDevice usbDevice) {

        Log.d(TAG, "Checkpermission: VID =" + usbDevice.getVendorId() + "  PID =" + usbDevice.getProductId());
        mUsbDriver = UsbSerialProber.getDefaultProber().probeDevice(usbDevice);
        mUsbPort = mUsbDriver.getPorts().get(0);
        musbDeviceConnection = usbManager.openDevice(usbDevice);
        try {

            mUsbPort.open(musbDeviceConnection);
            mUsbPort.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
            mSerialIoManager = new SerialInputOutputManager(mUsbPort, mSerialPortEventListener);
            mExecutor.execute(mSerialIoManager);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private final BroadcastReceiver Br_UsbActionProc = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent == null) {
                return;
            }
            switch (intent.getAction()) {
                case USB_SERIALPORT_ATTCHED:
                    Log.d(TAG, "onReceive: USB 插入处理");
                    CheckUsbDevice();
                    break;
                case USB_SERIALPORT_DETACHED:
                    Log.d(TAG, "onReceive: USB 拔出处理");
                    if(mUsbPort!=null)
                    {
                        try {
                            mUsbPort.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }

                    if (musbDeviceConnection!=null)
                    {
                        musbDeviceConnection.close();
                    }
                    mSerialIoManager.stop();
                    break;
            }
        }
    };

    private void CheckUsbDevice() {
        UsbManager usbManager = (UsbManager) getBaseContext().getSystemService(Context.USB_SERVICE);
        PendingIntent mPendingIntent = PendingIntent.getBroadcast(getBaseContext(), 0, new Intent(ACTION_USB_PERMISSION), 0);
        for (final UsbDevice usbDevice : usbManager.getDeviceList().values()) {
            Log.d(TAG, "CheckUsbDevice: VID =" + usbDevice.getVendorId() + "  PID =" + usbDevice.getProductId());
            mUsbDriver = UsbSerialProber.getDefaultProber().probeDevice(usbDevice);
            if (mUsbDriver==null)
            {
                Log.d(TAG, "CheckUsbDevice:非法设备");
                return;
            }
            if (usbManager.hasPermission(usbDevice)) {
                InitSerialPort(usbManager,usbDevice); //具有权限 直接启动
            } else {
                /**先申请权限**/
                usbManager.requestPermission(usbDevice, mPendingIntent);
            }
        }

    }

    public static class Br_UsbAction extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent == null) {
                return;
            }
            switch (intent.getAction()) {
                case UsbManager.ACTION_USB_DEVICE_ATTACHED: {
                    Log.d(TAG, "onReceive: USB 插入");
                    Intent bintent = new Intent();
                    bintent.setAction(ConnectService.USB_SERIALPORT_ATTCHED);
                    context.sendBroadcast(bintent);
                }
                break;
                case UsbManager.ACTION_USB_DEVICE_DETACHED: {
                    Log.d(TAG, "onReceive: USB 拔出");
                    Intent bintent = new Intent();
                    bintent.setAction(ConnectService.USB_SERIALPORT_DETACHED);
                    context.sendBroadcast(bintent);
                }
                break;
            }
        }
    }

    private final SerialInputOutputManager.Listener mSerialPortEventListener =
            new SerialInputOutputManager.Listener() {
                @Override
                public void onNewData(byte[] data) {
                    String str = new String(data);
                    Log.d(TAG, "onNewData: " + str);
                    mSerialIoManager.writeAsync(data);
                }

                @Override
                public void onRunError(Exception e) {

                }
            };

}
